// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf

#ifndef MGCCONTROLLER_MCR
#define MGCCONTROLLER_MCR

class MgcController;

// insert in root class declaration
#define MgcDeclareRootController \
    public: \
        bool AttachControl (MgcController* pkControl); \
        bool DetachControl (MgcController* pkControl); \
        void DestroyAllControllers (); \
        MgcController* GetControllers (); \
    protected: \
        MgcController* m_pkControl;

// insert in source file of root class of inheritance tree
#define MgcImplementRootController(classname) \
    bool classname::AttachControl (MgcController* pkControl) \
    { \
        if ( pkControl && !pkControl->m_pkObject && !pkControl->m_pkNext ) \
        { \
            pkControl->SetObject(this); \
            pkControl->m_pkNext = m_pkControl; \
            m_pkControl = pkControl; \
            return true; \
        } \
        return false; \
    } \
    \
    bool classname::DetachControl (MgcController* pkControl) \
    { \
        /* caller is responsible for deleting pkControl */ \
        if ( pkControl && m_pkControl ) \
        { \
            if ( pkControl == m_pkControl ) \
            { \
                /* controller at front of list, remove it */ \
                pkControl->SetObject(0); \
                m_pkControl = pkControl->m_pkNext; \
                return true; \
            } \
            \
            /* search for controller */ \
            MgcController* pkPrevious = m_pkControl; \
            MgcController* pkCurrent = pkPrevious->m_pkNext; \
            while ( pkCurrent && pkCurrent != pkControl ) \
            { \
                pkPrevious = pkCurrent; \
                pkCurrent = pkCurrent->m_pkNext; \
            } \
            if ( pkCurrent ) \
            { \
                /* found the controller, remove it */ \
                pkControl->SetObject(0); \
                pkPrevious->m_pkNext = pkControl->m_pkNext; \
                return true; \
            } \
        } \
        return false; \
    } \
    \
    void classname::DestroyAllControllers () \
    { \
        while ( m_pkControl ) \
        { \
            MgcController* pkSave = m_pkControl->m_pkNext; \
            delete m_pkControl; \
            m_pkControl = pkSave; \
        } \
    } \
    \
    MgcController* classname::GetControllers () \
    { \
        return m_pkControl; \
    }

#endif
